package net.huashitong.ssydt.provider.exam.service;


import net.huashitong.ssydt.exam.constant.ExamConsts;
import net.huashitong.ssydt.exam.entity.SsExamQuestion;
import net.huashitong.ssydt.exam.entity.SsExamQuestionOption;
import net.huashitong.ssydt.exam.entity.vo.ExamQuestion;
import net.huashitong.ssydt.exam.entity.vo.ExamQuestionQueryInVO;
import net.huashitong.ssydt.exam.entity.vo.QuestionCountVO;
import net.huashitong.ssydt.exam.entity.vo.QuestionNotTestVO;
import net.huashitong.ssydt.exceptions.ParamErrorServiceException;
import net.huashitong.ssydt.exceptions.ServiceException;
import net.huashitong.ssydt.provider.exam.dto.PaperProduceDTO;
import net.huashitong.ssydt.provider.exam.dto.PkLastYearDTO;
import net.huashitong.ssydt.provider.exam.mapper.SsExamQuestionMapper;
import net.huashitong.ssydt.provider.web.model.PaginationResult;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * @author hemj
 * @version 2017/8/25
 */
@Service
@Transactional
public class SsExamQuestionServiceImpl implements SsExamQuestionService {

    private SsExamQuestionMapper ssExamQuestionMapper;
    private SsExamQuestionOptionService ssExamQuestionOptionService;

    @Autowired
    public SsExamQuestionServiceImpl(SsExamQuestionMapper ssExamQuestionMapper,
                                     SsExamQuestionOptionService ssExamQuestionOptionService) {
        this.ssExamQuestionMapper = ssExamQuestionMapper;
        this.ssExamQuestionOptionService = ssExamQuestionOptionService;
    }

    @Transactional(propagation = Propagation.NEVER)
    @Override
    public PaginationResult<SsExamQuestion> paginationQuery(ExamQuestionQueryInVO examQuestionQueryInVO) {
        PaginationResult result = new PaginationResult();
        result.setPageNumber(examQuestionQueryInVO.getPageNumber());
        result.setPageSize(examQuestionQueryInVO.getPageSize());

        // 查询记录总数
        int total = ssExamQuestionMapper.paginationCount(examQuestionQueryInVO);
        result.setPageRecords(total);

        if (total == 0) {
            result.setList(new ArrayList());
        } else {
            // 查询当前页记录
            List<SsExamQuestion> list = ssExamQuestionMapper.paginationQuery(examQuestionQueryInVO);
            result.setList(list);
        }
        return result;
    }

    @Override
    public int countByDomestic(QuestionCountVO questionCountVO) {
        return ssExamQuestionMapper.countByDomestic(questionCountVO);
    }

    @Override
    public int countByDomesticAndTheProvince(QuestionCountVO questionCountVO) {
        return ssExamQuestionMapper.countByDomesticAndTheProvince(questionCountVO);
    }

    @Override
    public int countByDomesticAndInternational(QuestionCountVO questionCountVO) {
        return ssExamQuestionMapper.countByDomesticAndInternational(questionCountVO);
    }

    @Override
    public int countByDomesticAndInternationalAndTheProvince(QuestionCountVO questionCountVO) {
        return ssExamQuestionMapper.countByDomesticAndInternationalAndTheProvince(questionCountVO);
    }

    @Transactional(propagation = Propagation.NEVER)
    @Override
    public ExamQuestion getQuestionInfo(Long id) {
        SsExamQuestion ssExamQuestion = ssExamQuestionMapper.selectByPrimaryKey(id);
        if (ssExamQuestion == null) {
            throw new ServiceException("题目不存在");
        }

        List<SsExamQuestionOption> list = ssExamQuestionOptionService.listByQuestionId(id);

        ExamQuestion examQuestion = new ExamQuestion();
        BeanUtils.copyProperties(ssExamQuestion, examQuestion);
        examQuestion.setOptions(list);

        return examQuestion;
    }

    @Override
    public Long addQuestionInfo(ExamQuestion examQuestion) {
        checkQuestionInfo(examQuestion);

        SsExamQuestion ssExamQuestion = new SsExamQuestion();
        BeanUtils.copyProperties(examQuestion, ssExamQuestion);
        ssExamQuestionMapper.insertSelective(ssExamQuestion);
        List<SsExamQuestionOption> list = examQuestion.getOptions();
        for (SsExamQuestionOption ssExamQuestionOption : list) {
            ssExamQuestionOption.setQuestionId(ssExamQuestion.getId());
        }
        ssExamQuestionOptionService.multipleInsert(list);

        return ssExamQuestion.getId();
    }

    @Override
    public void updateQuestionInfo(ExamQuestion examQuestion) {
        checkQuestionInfo(examQuestion);

        SsExamQuestion ssExamQuestion = ssExamQuestionMapper.selectByPrimaryKey(examQuestion.getId());
        if (ssExamQuestion == null) {
            throw new ServiceException("题目不存在");
        }

        ssExamQuestionOptionService.deleteByQuestionId(examQuestion.getId());
        ssExamQuestionOptionService.multipleInsert(examQuestion.getOptions());

        BeanUtils.copyProperties(examQuestion, ssExamQuestion);
        ssExamQuestionMapper.updateByPrimaryKeySelective(ssExamQuestion);
    }

    @Override
    public void deleteQuestion(Long id) {
        // 删除题目信息（非必需）
        ssExamQuestionOptionService.deleteByQuestionId(id);
        ssExamQuestionMapper.deleteByPrimaryKey(id);
    }

    @Override
    public SsExamQuestion getById(Long id) {
        return ssExamQuestionMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<SsExamQuestion> queryByDomesticWithNotTest(QuestionNotTestVO questionNotTestVO) {
        return ssExamQuestionMapper.queryByDomesticWithNotTest(questionNotTestVO);
    }

    @Override
    public List<SsExamQuestion> queryByDomesticAndTheProvinceWithNotTest(QuestionNotTestVO questionNotTestVO) {
        return ssExamQuestionMapper.queryByDomesticAndTheProvinceWithNotTest(questionNotTestVO);
    }

    @Override
    public List<SsExamQuestion> queryByDomesticAndInternationalWithNotTest(QuestionNotTestVO questionNotTestVO) {
        return ssExamQuestionMapper.queryByDomesticAndInternationalWithNotTest(questionNotTestVO);
    }

    @Override
    public List<SsExamQuestion> queryByDomesticAndInternationalAndTheProvinceWithNotTest(QuestionNotTestVO questionNotTestVO) {
        return ssExamQuestionMapper.queryByDomesticAndInternationalAndTheProvinceWithNotTest(questionNotTestVO);
    }

    @Override
    public void update(SsExamQuestion ssExamQuestion) {
        ssExamQuestionMapper.updateByPrimaryKey(ssExamQuestion);
    }

    @Override
    public List<SsExamQuestion> queryByAreaWithAreaTypesWithTopics(String area, List<String> areaTypes, List<String> topics, String belongYearMonth) {
        PaperProduceDTO dto = new PaperProduceDTO();
        dto.setAreaTypes(areaTypes);
        dto.setArea(area);
        dto.setTopics(topics);
        dto.setBelongYearMonth(belongYearMonth);
        return ssExamQuestionMapper.queryByAreaWithAreaTypesWithTopics(dto);
    }

    @Override
    public List<SsExamQuestion> queryByLikeBelongDate(String belongDate) {
        return ssExamQuestionMapper.queryByLikeBelongDate(belongDate);
    }

    @Override
    public void logicDelete(Long questionId) {
        SsExamQuestion question = getById(questionId);
        if (question != null) {
            question.setIsDelete((byte) 1);
            update(question);
        }
    }

    @Override
    public List<SsExamQuestion> queryTenQuestionForLastYearByQuestionIdNotIn(List<Long> ids) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, 1);
        SimpleDateFormat yearSdf = new SimpleDateFormat("yyyy");
        SimpleDateFormat monthSdf = new SimpleDateFormat("MM");
        String endYear = yearSdf.format(calendar.getTime());
        String endMonth = monthSdf.format(calendar.getTime());

        calendar.set(Calendar.MONTH, -13);
        String startYear = yearSdf.format(calendar.getTime());
        String startMonth = monthSdf.format(calendar.getTime());

        PkLastYearDTO dto = new PkLastYearDTO();
        dto.setStartDate(String.format("%s-%s", startYear, startMonth));
        dto.setEndDate(String.format("%s-%s", endYear, endMonth));
        if (ids != null) {
            dto.setIds(ids);
        }
        return ssExamQuestionMapper.queryTenQuestionForLastYearByQuestionIdNotIn(dto);
    }

    @Override
    public List<SsExamQuestion> queryTenQuestionForLastYear() {
        return this.queryTenQuestionForLastYearByQuestionIdNotIn(null);
    }

    @Override
    public List<SsExamQuestion> findFiveQuestionByNowDate(String dateStr) {
        return ssExamQuestionMapper.findFiveQuestionByNowDate(dateStr);
    }

    private void checkQuestionInfo(ExamQuestion examQuestion) {
        switch (examQuestion.getAreaType()) {
            case ExamConsts.AreaType.DOMESTIC:
                break;
            case ExamConsts.AreaType.THE_PROVINCE:
                if (StringUtils.isBlank(examQuestion.getArea())) {
                    throw new ParamErrorServiceException("请选择地区");
                }
                break;
            case ExamConsts.AreaType.INTERNATIONAL:
                break;
            default:
                throw new ParamErrorServiceException("地区类型输入错误");
        }

        int correct = 0; // 正确答案个数统计
        List<SsExamQuestionOption> list = examQuestion.getOptions();

        if (list.size() < 2) {
            throw new ParamErrorServiceException("至少需要两条答案选项");
        }
        for (SsExamQuestionOption ssExamQuestionOption : list) {
            if (StringUtils.isBlank(ssExamQuestionOption.getAnswer())) {
                throw new ParamErrorServiceException("答案内容不能为空");
            }
            if (ssExamQuestionOption.getIsTrue() != null && 1 == ssExamQuestionOption.getIsTrue()) { // 1:正确答案
                ++correct;
            } else {
                ssExamQuestionOption.setIsTrue((byte) 0); //0:非正确答案
            }
            if (ssExamQuestionOption.getSequence() == null) {
                ssExamQuestionOption.setSequence(99);
            }
            ssExamQuestionOption.setQuestionId(examQuestion.getId());
        }

        switch (examQuestion.getQuestionType()) {
            case "01": // 单选
                if (correct != 1) {
                    throw new ParamErrorServiceException("单选题有且仅有一个正确答案");
                }
                break;
            case "02": // 多选
                if (correct < 2) {
                    throw new ParamErrorServiceException("多选题至少需要两个正确答案");
                }
                break;
            case "03": // 不定项
                if (correct == 0) {
                    throw new ParamErrorServiceException("不定项题至少需要一个正确答案");
                }
                break;
            default:
                throw new ParamErrorServiceException("题目类型输入错误");
        }

        switch (examQuestion.getIsEmphasis()) {
            case 0:
            case 1:
                break;
            default:
                throw new ParamErrorServiceException("是否重点输入错误");
        }

        switch (examQuestion.getIsCard()) {
            case 0:
            case 1:
                break;
            default:
                throw new ParamErrorServiceException("是否时事卡输入错误");
        }
    }

}
